package com.imoblife.brainwavestus.oldDownloadFrame;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.imoblife.brainwavestus.model.Constant;
import com.imoblife.brainwavestus.service.DownLoadSchedulerSystem;
import com.imoblife.brainwavestus.util.DebugUtil;

import android.util.Log;


public class DownLoadItem implements Runnable {

	public static final String TAG = "DownLoadItem";

	public interface PrepareListener {

		public void prepare(String downlaodname, int extr, long progress,
				long size);
	}

	public interface CompleteListener {

		public void complete(String downlaodname, int extr, long progress,
				long size);
	}

	public interface DownLoadingListener {

		public void downloading(String downlaodname, int extr, long progress,
				long size);
	}

	private PrepareListener prepareListener;

	private CompleteListener completeListener;

	private static DownLoadingListener downLoadingListener;

	public static String urlRootPath;
	public static String rootPath;
	String name;
	String fomat;

	static {
		urlRootPath = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
		rootPath = "/sdcard/.brainwaves-tus/";
	}

	/**
	 * 
	 * @param urlRootPath
	 */
	public static void setUrlRootPath(String urlRootPath) {
		DownLoadItem.urlRootPath = urlRootPath;

	}

	public DownLoadItem(String name, String fomat) {
		this.name = name;
		this.fomat = fomat;
	}

	public void setPrepareListener(PrepareListener listener) {

		this.prepareListener = listener;

	}

	public int getLevel() {

		if (fomat.equals("prew")) {
			return DownLoadSchedulerSystem.LEVEL_PREW;
		}

		if (fomat.equals("music")) {
			return DownLoadSchedulerSystem.LEVEL_MUSIC;
		}

		if (fomat.equals("icon")) {
			return DownLoadSchedulerSystem.LEVEL_ICON;
		}

		if (fomat.equals("des")) {
			return DownLoadSchedulerSystem.LEVEL_DES;
		}
		return -1;
	}

	public void setCompleteListener(CompleteListener listener) {
		

		this.completeListener = listener;
	}

	public static void setDownLoadingListener(DownLoadingListener Listener) {
		downLoadingListener = Listener;
	}

	public static DownLoadingListener getDownLoadingListener() {

		return downLoadingListener;

	}

	public String getPath() {

		String subPath = null;

		if (fomat.equals("icon")) {
			subPath = "icon/" + name + ".icon";
		} else if (fomat.equals("music")) {
			subPath = "music/" + name + ".music";
		} else if (fomat.equals("des")) {
			subPath = "des/" + name + ".des";
		} else {
			assert ("subPath=null" == null);
		}

		return rootPath + subPath;
	}

	public String getDirPath() {
		String subPath = null;

		if (fomat.equals("icon")) {
			subPath = "icon/";
		} else if (fomat.equals("music")) {
			subPath = "music/";
		} else if (fomat.equals("des")) {
			subPath = "des/";
		} else if (fomat.equals("prew")) {
			subPath = "prew/";
		}

		return rootPath + subPath;
	}

	public String getSubPath() {

		String subPath = null;

		if (fomat.equals("icon")) {
			subPath = name + ".icon";
		} else if (fomat.equals("music")) {
			subPath = name + ".music";
		} else if (fomat.equals("des")) {
			subPath = name + ".des";
		} else if (fomat.equals("prew")) {
			subPath = name + ".prew";
		}

		else {
			assert ("subPath=null" == null);
		}

		return subPath;

	}


	public String getUrlPath() {
		String subPath = null;

		if (fomat.equals("icon")) {
			subPath = "icon/" + name + ".icon";
		} else if (fomat.equals("music")) {
			subPath = "music/" + name + ".music";
		} else if (fomat.equals("des")) {
			subPath = "des/" + name + ".des";
		} else if (fomat.equals("prew")) {
			subPath = "prew/" + name + ".prew";
		}

		else {
			assert ("subUrl=null" == null);
		}
		
		DebugUtil.netDebug(TAG, "request url:" + urlRootPath + subPath);
		
		//如果是测试环境，返回固定的url
		if (DebugUtil.netDebug) {
			
			//预览音频文件地址
			//if(subPath.contains("prew")){
				
				return Constant.TEST_URL;
				
			//	return "http://qd.baidupcs.com/file/2bb14c4ce0abcd26134ce408d8c29ac7?xcode=a4449f8344175ca8f8f489c44c79c2355a7185229e4385b9&fid=758205429-250528-3128356432&time=1373333608&sign=FDTAXER-DCb740ccc5511e5e8fedcff06b081203-d7yB6KqJPsULvAaYW7nwXHEt83Y%3D&to=qb&fm=Q,Q,U&expires=8h&rt=pr&r=237686285&logid=1882103034&fn=Chakra%20Opening.mp3";
			//}
			
		}else{
			return urlRootPath + subPath;
		}

	}

	public long getProgress() throws IOException {
		RandomAccessFile accessFile = getSaveFile();
		return accessFile.length();
	}

	private long getStartOffset(RandomAccessFile accessFile) throws IOException {

		return accessFile.length();

	}

	private URL getUrl() throws MalformedURLException {
		return new URL(getUrlPath());
	}

	private HttpURLConnection getConnection(URL url) throws IOException {

		return (HttpURLConnection) url.openConnection();
	}

	private int setHttpDownLoadStart(long start, HttpURLConnection connection,
			RandomAccessFile file) throws IOException {

		connection.setRequestMethod("GET");
		connection.setConnectTimeout(6000);
		connection.setReadTimeout(9000);
		connection.setAllowUserInteraction(true);
		connection.setRequestProperty("Range", "bytes=" + start + "-");
		connection.connect();

		int responseCode = connection.getResponseCode();

		if (responseCode == -1 || responseCode == 416) {
			return responseCode;
		}

		file.seek(start);

		return responseCode;

	}

	public String getDataName() {

		return name + "." + fomat;

	}

	HttpURLConnection httpURLConnection;

	public void run() {

		InputStream inputStream = null;
		RandomAccessFile singleInstenceFile = null;
		
		DebugUtil.debug(TAG, "down thread begin run");
		
		try {

			singleInstenceFile = getSaveFile();
		
			long startOffset = getStartOffset(singleInstenceFile);
			
			URL url = getUrl();
			
			DebugUtil.netDebug(TAG, "open url fail");
			
			httpURLConnection = getConnection(url);
			
			DebugUtil.netDebug(TAG, "open url success");
			
			int responseCode = setHttpDownLoadStart(startOffset,
					httpURLConnection, singleInstenceFile);
			
			DebugUtil.debug(TAG, "responseCode: " + responseCode);
			
			if (responseCode == 416) {

				httpURLConnection.disconnect();
				singleInstenceFile.close();

				if (prepareListener != null) {
					prepareListener.prepare(name + "." + fomat,
							DownLoadItemPragrame.EXTR_SUCC, startOffset,
							startOffset);
				}

				if (completeListener != null) {
					completeListener.complete(name + "." + fomat,
							DownLoadItemPragrame.EXTR_SUCC, startOffset,
							startOffset);
				}

				if (downLoadingListener != null) {
					downLoadingListener.downloading(name + "." + fomat,
							DownLoadItemPragrame.EXTR_SUCC, startOffset,
							startOffset);
				}
				return;
				
			} else if (responseCode == -1) {
				httpURLConnection.disconnect();
				singleInstenceFile.close();

				if (prepareListener != null) {
					prepareListener.prepare(name + "." + fomat,
							DownLoadItemPragrame.EXTR_FAILE_NET, 0, 0);
				}

				if (completeListener != null) {
					completeListener.complete(name + "." + fomat,
							DownLoadItemPragrame.EXTR_FAILE_NET, 0, 0);
				}

				if (downLoadingListener != null) {
					downLoadingListener.downloading(name + "." + fomat,
							DownLoadItemPragrame.EXTR_FAILE_NET, 0, 0);
				}

				return;

			} else if (responseCode == 206) {
				DebugUtil.debug(TAG, getTaskName() + " == " + startOffset);
			}
	
			long length = httpURLConnection.getContentLength();

			length += startOffset;
			
			DebugUtil.dbDebug(TAG, "content length: " + length);
			
			if (isRunning && prepareListener != null) {
				prepareListener.prepare(name + "." + fomat,
						DownLoadItemPragrame.EXTR_SUCC, startOffset, length);
			}


			inputStream = httpURLConnection.getInputStream();

			byte[] buffer = new byte[1024];
			int len = 0;

			while ((len = inputStream.read(buffer)) != -1) {

				if (isRunning) {
					
					//DebugUtil.netDebug(TAG, "start download file now~");
					singleInstenceFile.write(buffer, 0, len);
					if (downLoadingListener != null) {
						
						//DebugUtil.netDebug(TAG, "write progress");
						downLoadingListener.downloading(name + "." + fomat,
								DownLoadItemPragrame.EXTR_SUCC, startOffset,
								length);
					}
					startOffset += len;
				
				} else {

					singleInstenceFile.write(buffer, 0, len);

					singleInstenceFile.close();
					httpURLConnection.disconnect();
					inputStream.close();

					if (downLoadingListener != null) {
						downLoadingListener.downloading(name + "." + fomat,
								DownLoadItemPragrame.EXTR_INTERRUPT, 0, 0);
					}
					if (completeListener != null) {
						completeListener.complete(name + "." + fomat,
								DownLoadItemPragrame.EXTR_INTERRUPT, 0, 0);
					}
					return;
				}
			}

			singleInstenceFile.close();
			httpURLConnection.disconnect();
			inputStream.close();

			if (isRunning) {

				if (completeListener != null) {
					completeListener
							.complete(name + "." + fomat,
									DownLoadItemPragrame.EXTR_SUCC,
									startOffset, length);
				}

				if (downLoadingListener != null) {

					downLoadingListener
							.downloading(name + "." + fomat,
									DownLoadItemPragrame.EXTR_SUCC,
									startOffset, length);
				}

			} else {

				if (completeListener != null) {
					completeListener.complete(name + "." + fomat,
							DownLoadItemPragrame.EXTR_INTERRUPT, -1, -1);
				}

				if (downLoadingListener != null) {
					downLoadingListener.downloading(name + "." + fomat,
							DownLoadItemPragrame.EXTR_INTERRUPT, startOffset,
							length);
				}
			}

			return;

		} catch (IOException e) {
			
			DebugUtil.debug(TAG, "catch exception: " + e.getMessage());
			
			if (!isRunning) {

				if (downLoadingListener != null) {
					downLoadingListener.downloading(name + "." + fomat,
							DownLoadItemPragrame.EXTR_INTERRUPT, -1, -1);
				}

				if (completeListener != null) {

					completeListener.complete(name + "." + fomat,
							DownLoadItemPragrame.EXTR_INTERRUPT, -1, -1);
				}

			} else if (e.getMessage().contains("sdcard")
					|| e.getMessage().contains("Permission denied")
					|| e.getMessage().contains("No space left on device")) {

				if (downLoadingListener != null) {
					downLoadingListener.downloading(name + "." + fomat,
							DownLoadItemPragrame.EXTR_FAILE_SDCARDE, -1, -1);
				}

				if (completeListener != null) {

					completeListener.complete(name + "." + fomat,
							DownLoadItemPragrame.EXTR_FAILE_SDCARDE, -1, -1);
				}
				// 3 �������
			} else {

				if (downLoadingListener != null) {
					downLoadingListener.downloading(name + "." + fomat,
							DownLoadItemPragrame.EXTR_FAILE_NET, -1, -1);
				}

				if (completeListener != null) {

					completeListener.complete(name + "." + fomat,
							DownLoadItemPragrame.EXTR_FAILE_NET, -1, -1);
				}
			}

			try {
				singleInstenceFile.close();
				inputStream.close();
			} catch (Exception e2) {
				
			}

		}

	}

	/**
	 * ��ȡ�ϴα����ļ�
	 * 
	 * @return
	 * @throws IOException
	 */
	private RandomAccessFile getSaveFile() throws IOException {

		File file = new File(getDirPath());

		if (!file.exists()) {
			file.mkdirs();
		}

		file = new File(file, getSubPath());
		if (!file.exists()) {
			file.createNewFile();
		}

		return new RandomAccessFile(file, "rwd");

	}

	public void setRedowmLoad() {

		File file = new File(getDirPath());

		if (!file.exists()) {
			file.mkdirs();
		}

		file = new File(file, getSubPath());

		if (file.exists()) {
			
			boolean b = file.delete();
		}
	}

	public long getMaxSize() {
		
		return 0;
	}

	public boolean isRunning = true;

	/**
	 * �������
	 */
	public synchronized void interrupt() {

		isRunning = false;
		try {
			httpURLConnection.disconnect();
		} catch (Exception e) {
			
		}

	}

	/**
	 * ����Ƿ���
	 * 
	 * @return
	 */
	public synchronized boolean isInterrupted() {

		return !isRunning;

	}

	public String getfomat() {
		return fomat;
	}

	public String getName() {
		return name;
	}

	public String getTaskName() {
		return name + "." + fomat;
	}

}
